package xyz.xtt.pay.service.order;

import static xyz.xtt.common.asset.AssertUtils.isFalse;
import static xyz.xtt.common.asset.AssertUtils.isNull;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.api.enums.GoodsTypeEnum;
import xyz.xtt.asset.client.response.AssetInfoResponse;
import xyz.xtt.asset.client.response.AssetNoResponse;
import xyz.xtt.asset.client.response.AssetStaticResponse;
import xyz.xtt.pay.api.enums.PayOrderBusinessTypeEnum;
import xyz.xtt.pay.api.enums.PayOrderStatusEnum;
import xyz.xtt.pay.client.request.MakeOrderRequest;
import xyz.xtt.pay.constants.ErrorMessage;
import xyz.xtt.pay.constants.PayConstants;
import xyz.xtt.pay.entity.TblBusinessOrder;
import xyz.xtt.pay.service.BusinessOrderOperator;
import xyz.xtt.pay.service.IInnerService;
import xyz.xtt.pay.service.INftOrderService;
import xyz.xtt.pay.service.ITblBusinessOrderService;

/**
 * @author dale
 * @date 2025/3/17
 **/
@Service
@RefreshScope
@Slf4j
public class NftCardBusinessOrderOperator implements BusinessOrderOperator {
	@Autowired
	private INftOrderService nftOrderService;
	@Autowired
	private ITblBusinessOrderService iTblBusinessOrderService;
	@Value("${nftCardUnitPrice:16}")
	private float nftCardUnitPrice;
	@Autowired
	private IInnerService iInnerService;

	/**
	 * 是否支持该类型的订单
	 *
	 * @param type
	 * @return
	 */
	@Override
	public boolean canOperateType(PayOrderBusinessTypeEnum type) {
		return Objects.equals(type, PayOrderBusinessTypeEnum.NFT_CARD);
	}

	/**
	 * 创建订单
	 *
	 * @param uid              用户ID
	 * @param makeOrderRequest 创建订单请求
	 * @return 订单
	 */
	@Override
	public TblBusinessOrder makeOrder(String uid, MakeOrderRequest makeOrderRequest) {
		long assetNoId = Long.parseLong(makeOrderRequest.getAssetNoId());
		long receiveAddressId = Long.parseLong(makeOrderRequest.getReceiveAddressId());
		long buyerId = Long.parseLong(uid);
		AssetNoResponse assetNo = iInnerService.assetNoInfoWithNoId(assetNoId);
		isNull(assetNo, ErrorMessage.ASSET_NO_NOT_EXIST);
		isFalse(Objects.equals(assetNo.getAppUserId(), buyerId), ErrorMessage.ASSET_NO_NOT_OWN);
		isFalse(Objects.equals(assetNo.getAssetType(), 0), ErrorMessage.ASSET_NO_STATUS_ERROR);
		AssetInfoResponse asset = iInnerService.infoWithAssetId(assetNo.getAssetId());
		AssetStaticResponse assetStaticResource = iInnerService.staticInfoWithAssetId(assetNo.getAssetId());
		GoodsTypeEnum goodsTypeEnum = GoodsTypeEnum.valueOf(makeOrderRequest.getOrderType());
		String goodsId = String.valueOf(assetNoId);
		// 检查是否有待支付的订单
		TblBusinessOrder unPayOrder = iTblBusinessOrderService.getUnPayBusinessOrder(buyerId, goodsTypeEnum.getCode(), goodsId);
		if (unPayOrder != null) {
			return unPayOrder;
		}

		TblBusinessOrder order = new TblBusinessOrder();
		order.setOrderId(IdUtil.getSnowflakeNextId());
		order.setGoodsId(goodsId);
		order.setGoodsType(goodsTypeEnum.getCode());
		order.setGoodsName(asset.getAssetName() + "卡牌");
		order.setGoodsImage(assetStaticResource.getLogoUri());
		order.setSellerId(PayConstants.TONGTONG_PLATFROM_USER_ID);
		order.setAppUserId(buyerId);
		order.setPurchaseNum(makeOrderRequest.getPurchaseAmount());
		BigDecimal unitPrice = new BigDecimal(nftCardUnitPrice).setScale(2, RoundingMode.HALF_UP);
		// 测试用户重置价格
		unitPrice = nftOrderService.testUserResetPrice(buyerId, unitPrice);
		order.setOriginPrice(unitPrice);
		order.setRealPrice(order.getOriginPrice());
		order.setTransportPrice(BigDecimal.ZERO);
		order.setDiscountAmount(BigDecimal.ZERO);
		order.setTotalPrice(calculateOrderTotalPrice(order));
		order.setPayAmount(order.getTotalPrice());
		order.setReceiveAddressId(receiveAddressId);
		order.setOrderStatus(PayOrderStatusEnum.UN_PAY.getCode());
		LocalDateTime now = LocalDateTime.now();
		order.setOrderTime(now);
		order.setCreateTime(now);
		order.setUpdateTime(now);
		order.setBusinessRefId(String.valueOf(order.getOrderId()));
		isFalse(iTblBusinessOrderService
				.save(order), ErrorMessage.ORDER_CREATE_FAILED, () -> log.error("save order failed. order:{}", JSONUtil.toJsonStr(order)));
		return order;
	}
}
